import math
import numpy as np
import matplotlib.pyplot as plt
from itertools import permutations, combinations
from collections import Counter
import scipy.stats as stats


def set_chinese_font():
    """设置中文字体"""
    plt.rcParams['font.sans-serif'] = ['SimHei', 'Microsoft YaHei', 'DejaVu Sans']
    plt.rcParams['axes.unicode_minus'] = False  # 解决负号显示问题

set_chinese_font()

def calculus_basics():
    print("=== 微积分基础 ===")
    
    # 导数
    x = sp.Symbol('x')
    f = x**3 - 3*x**2 + 2*x + 1
    f_prime = sp.diff(f, x)
    f_double_prime = sp.diff(f, x, 2)
    
    print(f"函数 f(x) = {f}")
    print(f"一阶导数 f'(x) = {f_prime}")
    print(f"二阶导数 f''(x) = {f_double_prime}")
    
    # 在特定点的导数值
    x0 = 2
    f_prime_at_x0 = f_prime.subs(x, x0)
    print(f"在 x={x0} 处的导数值: {f_prime_at_x0}")
    
    # 积分
    indefinite_integral = sp.integrate(f, x)
    definite_integral = sp.integrate(f, (x, 0, 2))
    
    print(f"\n不定积分 ∫f(x)dx = {indefinite_integral} + C")
    print(f"定积分 ∫₀²f(x)dx = {definite_integral}")
    
    # 可视化
    x_vals = np.linspace(-1, 3, 400)
    
    # 将符号表达式转换为数值函数
    f_lambdified = sp.lambdify(x, f, 'numpy')
    f_prime_lambdified = sp.lambdify(x, f_prime, 'numpy')
    
    y_vals = f_lambdified(x_vals)
    y_prime_vals = f_prime_lambdified(x_vals)
    
    fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5))
    
    # 函数和导数
    ax1.plot(x_vals, y_vals, 'b-', label=f'f(x) = {sp.latex(f)}', linewidth=2)
    ax1.plot(x_vals, y_prime_vals, 'r-', label=f"f'(x) = {sp.latex(f_prime)}", linewidth=2)
    ax1.axhline(0, color='black', linewidth=0.5)
    ax1.axvline(0, color='black', linewidth=0.5)
    ax1.grid(True)
    ax1.legend()
    ax1.set_title('函数及其导数')
    
    # 积分面积
    x_integral = np.linspace(0, 2, 100)
    y_integral = f_lambdified(x_integral)
    ax2.plot(x_vals, y_vals, 'b-', label=f'f(x)', linewidth=2)
    ax2.fill_between(x_integral, y_integral, alpha=0.3, color='green', label='积分面积')
    ax2.axhline(0, color='black', linewidth=0.5)
    ax2.axvline(0, color='black', linewidth=0.5)
    ax2.grid(True)
    ax2.legend()
    ax2.set_title(f'定积分 ∫₀²f(x)dx = {definite_integral:.2f}')
    
    plt.tight_layout()
    plt.show()

calculus_basics()